package com.tangyuan.user.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.tangyuan.common.constant.RedisConstant;
import com.tangyuan.common.result.Result;
import com.tangyuan.common.result.ResultCodeEnum;
import com.tangyuan.common.util.*;
import com.tangyuan.dto.UpdateHeadlinesDto;
import com.tangyuan.dto.UserSetPhoneNumberDto;
import com.tangyuan.dto.VideoPublisherDto;
import com.tangyuan.feignapis.headlines.IHeadlinesCommentFeignClient;
import com.tangyuan.feignapis.headlines.IHeadlinesFeignClient;
import com.tangyuan.feignapis.video.IVideoCommentFeignClient;
import com.tangyuan.feignapis.video.IVideoFeignClient;
import com.tangyuan.model.User;
import com.tangyuan.user.mapper.UserBlackListMapper;
import com.tangyuan.user.mapper.UserConcernMapper;
import com.tangyuan.user.mapper.UserInfoMapper;
import com.tangyuan.user.service.IUserService;
import com.tangyuan.user.service.UserConcernService;
import com.tangyuan.user.service.UserInfoService;
import com.tangyuan.vo.AndroidVersion;
import com.tangyuan.vo.IosVersion;
import com.tangyuan.vo.UserSettingInfoVo;
import com.tangyuan.vo.VersionVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class UserInfoServiceImpl implements UserInfoService {
    @Autowired
    UserInfoMapper userInfoMapper;
    @Autowired
    UserBlackListMapper userBlackListMapper;
    @Autowired
    UserConcernService userConcernService;
    @Autowired
    IUserService iUserService;
    @Autowired
    UserConcernMapper userConcernMapper;

    @Autowired
    private IVideoFeignClient videoFeignClient;
    @Autowired
    private IHeadlinesFeignClient headlinesFeignClient;
    @Autowired
    private IHeadlinesCommentFeignClient headlinesCommentFeignClient;

    @Autowired
    private IVideoCommentFeignClient videoCommentFeignClient;

    @Value("${spring.profiles.active}")
    private String env;

    @Override
    public Result getSettingInfo(Long userId) {

        User user = iUserService.getUserById(userId);
        UserSettingInfoVo userSettingInfoVo = new UserSettingInfoVo();
        userSettingInfoVo.setName(user.getName());
        userSettingInfoVo.setHeadImage(user.getHeadImage());
        userSettingInfoVo.setBirthDay(user.getBirthDay());
        userSettingInfoVo.setMobile(user.getMobile());
        userSettingInfoVo.setSex(user.getSex());
        return Result.ok(userSettingInfoVo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result handleFileUpload(MultipartFile file, String token,String url) {
        User user = CommStatus.getUser(token);
        Long id = user.getId();
        //调用阿里OSS上传头像 获取头像url
        if (url == null){
            url = PictureOSSUtils.upload(file, FileNameUtil.getPngName());
        }

        iUserService.setUserById(User.HEAD_IMAGE,url, token);
        //修改百家文章中的头像
        UpdateHeadlinesDto updateHeadlinesDto = new UpdateHeadlinesDto();
        updateHeadlinesDto.setUrl(url);
        updateHeadlinesDto.setUserId(id);
        headlinesFeignClient.updateHeadlinesUserMessage(updateHeadlinesDto);

        // 修改百家评论头像 2024/4/22 下午2:17 By Wesin
        headlinesCommentFeignClient.updateHeadlinesCommentAvatar(updateHeadlinesDto);
        // 修改视频头像 2024/4/22 下午2:18 By Wesin
        VideoPublisherDto dto = new VideoPublisherDto(id, null, url);
        videoFeignClient.updateUserVideoMessage(dto);
        // 修改视频评论头像
        videoCommentFeignClient.updateVideoCommentMessage(dto);
        //修改我的关注的头像
        userConcernMapper.updateUserConcernImage(url,id);
        return Result.ok(url);
    }

    /**
     * 通用文件上传
     * @param file
     * @return
     */
    @Override
    public Result fileUpload(MultipartFile file) {
        // 获取上传文件后缀
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        //调用阿里OSS上传 获取url
        String name = LocalDateTime.now() + UUID.fastUUID().toString().substring(8).replaceAll("-", "");
        if (StringUtils.isNotBlank(suffix)) {
            name = name + suffix;
        }
        String url = PictureOSSUtils.upload(file, name);

        // 有必要的话应该建个表存储上传的文件url

        return Result.ok(url);
    }

    @Override
    public Result setNickName(String nickName, String token) {
        User user = CommStatus.getUser(token);
        Long id = user.getId();
        //更新用户昵称
        iUserService.setUserById(User.NAME,nickName,token);

        UpdateHeadlinesDto updateHeadlinesDto = new UpdateHeadlinesDto();
        updateHeadlinesDto.setNickName(nickName);
        updateHeadlinesDto.setUserId(id);
        headlinesFeignClient.updateHeadlinesUserMessage(updateHeadlinesDto);
        //更改名称时更改百家的发布人名称
       // userInfoMapper.setMediaInfoName(nickName,id);


        //更改名称时更改百家评论人名称
        headlinesCommentFeignClient.updateHeadlinesCommentName(updateHeadlinesDto);

        //更改名称时更改关注记录人名称
        userConcernMapper.updateUserConcernUserName(nickName,id);

        //更改名称时更改关注被关注名称
        userConcernMapper.updateConcernUserName(nickName,id);

        //更改名称时更改用户备注原名
        userInfoMapper.updateRemarkUserName(nickName,id);

        VideoPublisherDto videoPublisherDto = new VideoPublisherDto(id,nickName,null);
        //修改名称时更改小视频发布人名称
        videoFeignClient.updateUserVideoMessage(videoPublisherDto);


        //修改名称时更改视频评论用户名称
        videoCommentFeignClient.updateVideoCommentMessage(videoPublisherDto);

        user.setName(nickName);
        CommStatus.set(CommStatus.joinToken(token), user, RedisConstant.USER_CODE_TIMEOUT, TimeUnit.SECONDS);
        return Result.ok();
    }

    @Override
    public Result setPhoneNumberGetCode(String mobile) {
        String userMobileById = userInfoMapper.getUserMobileById(mobile);
        if (userMobileById == null) {
            return Result.build(null, ResultCodeEnum.USER_NOT_EXIST);
        }
        String CodePrefix = RedisConstant.USER_RESET_PHONE_CODE_PREFIX + mobile;
        CommStatus.delete(CodePrefix);
        //随机生成验证码
        // 生成一个6位数字验证码
        String code = RandomCodeUtil.getRandomCode();
        if ("dev".equalsIgnoreCase(env)) {
            code = "123456";
        } else {
            //发送验证码
            SmsUtil.sendMessage("盛唐风", "SMS_199300330", mobile, code);
        }
        //得到正确验证码先把验证码存在缓存里
        //设置验证码过期时间为5分钟
        CommStatus.set(CodePrefix, code, RedisConstant.USER_CODE_TIMEOUT, TimeUnit.SECONDS);
        return Result.ok();
    }


    @Override
    public Result setPhoneNumber(UserSetPhoneNumberDto userSetPhoneNumberDto) {
        //验证手机号是存在
        String mobile = userInfoMapper.getUserMobileById(userSetPhoneNumberDto.getMobile());
        if (mobile == null) {
            return Result.build(null, ResultCodeEnum.USER_NOT_EXIST);
        }
        //验证验证码是否正确
        String CodePrefix = RedisConstant.USER_RESET_PHONE_CODE_PREFIX + userSetPhoneNumberDto.getMobile();
        String code = CommStatus.get(CodePrefix).toString();
        if (code == null) {
            return Result.build(null, ResultCodeEnum.CODE_OVERTIME);
        }
        if (!code.equals(userSetPhoneNumberDto.getCode())) {
            return Result.build(null, ResultCodeEnum.PHONE_CODE_ERROR);
        }
        CommStatus.delete(CodePrefix);
        return Result.ok();
    }


    @Override
    public Result setNewPhoneNumberGetCode(String mobile) {
        //判断新手机号是否已经存在
        String checkMobile = userInfoMapper.getUserMobileById(mobile);
        //电话号已经存在
        if (checkMobile != null) {
            return Result.build(null, ResultCodeEnum.USER_EXIST);
        }
        String CodePrefix = RedisConstant.USER_RESET_NEW_PHONE_CODE_PREFIX + mobile;
        CommStatus.delete(CodePrefix);
        //随机生成验证码
        // 生成一个6位数字验证码
        String code = RandomCodeUtil.getRandomCode();
        if ("dev".equalsIgnoreCase(env)) {
            code = "123456";
        } else {
            //发送验证码
            SmsUtil.sendMessage("盛唐风", "SMS_199300330", mobile, code);
        }
        //得到正确验证码先把验证码存在缓存里
        //设置验证码过期时间为5分钟
        CommStatus.set(CodePrefix, code, RedisConstant.USER_CODE_TIMEOUT, TimeUnit.SECONDS);
        return Result.ok();
    }

    @Override
    public Result setNewPhoneNumber(UserSetPhoneNumberDto userSetPhoneNumberDto, String token) {
        //判断新手机号是否已经存在
        String newMobile = userInfoMapper.getUserMobileById(userSetPhoneNumberDto.getNewMobile());
        //电话号已经存在
        if (newMobile != null) {
            return Result.build(null, ResultCodeEnum.USER_EXIST);
        }
        //判断验证码是否正确
        String CodePrefix = RedisConstant.USER_RESET_NEW_PHONE_CODE_PREFIX + userSetPhoneNumberDto.getNewMobile();
        String tCode = CommStatus.get(CodePrefix).toString();
        if (tCode == null) {
            return Result.build(null, ResultCodeEnum.CODE_OVERTIME);
        }
        if (!tCode.equals(userSetPhoneNumberDto.getCode())) {
            return Result.build(null, ResultCodeEnum.PHONE_CODE_ERROR);
        }
        // 从token获取旧手机号
        User user = CommStatus.getUser(token);
        if (user == null) {
            return Result.build(null, ResultCodeEnum.FAIL_LOGIN);
        }
        iUserService.update(null,new LambdaUpdateWrapper<User>()
                .eq(User::getMobile,user.getMobile())
                .set(User::getMobile,userSetPhoneNumberDto.getNewMobile()));
        String onlineKey = RedisConstant.USER_ONLINE_KEY_PREFIX + userSetPhoneNumberDto.getMobile();
        //删除旧缓存
        CommStatus.delete(onlineKey);
        CommStatus.delete(CommStatus.joinToken(token));
        return Result.ok();
    }

    @Override
    public Result showBlackList(String token) {
        User user = CommStatus.getUser(token);
        Map map = new HashMap();
        map.put("black_list", userInfoMapper.getUserBlacklist(user.getId()));
        return Result.ok(map);
    }

    @Override
    public Result checkVersion() {
        VersionVo versionVo = userInfoMapper.checkVersion();
        return Result.ok(versionVo);
    }

    @Override
    public Result resetPassword(String prePasswd, String newPasswd, String token) {
        User user = CommStatus.getUser(token);
        if (!MD5.encrypt(prePasswd).equals(user.getPassword())){
            return Result.build(null,288,"输入原密码不正确");
        }
        iUserService.setUserById(User.PASSWORD,MD5.encrypt(newPasswd),token);
        user.setPassword(MD5.encrypt(newPasswd));

        CommStatus.set(CommStatus.joinToken(token),user);
        return Result.ok();
    }

    @Override
    public Result deleteUser(String token) {
        User user = CommStatus.getUser(token);
        if (user == null) {
            return Result.build(null, ResultCodeEnum.LOGIN_AUTH);
        }

        userInfoMapper.deleteUser(user.getId());
        CommStatus.delete(RedisConstant.USER_LOGIN_KEY_PREFIX + token);
        CommStatus.delete(RedisConstant.USER_ONLINE_KEY_PREFIX + user.getMobile());
        return Result.ok();
    }

    @Override
    public Result checkForceUpdate(String currentVersion, String deviceInfo) {
        if (StringUtils.isEmpty(currentVersion) || StringUtils.isEmpty(deviceInfo)) {
            return Result.build(null, ResultCodeEnum.ARGUMENT_VALID_ERROR);
        }
        switch (deviceInfo.toLowerCase()) {
            case "android":
                List<AndroidVersion> androidVersions = userInfoMapper.getAndroidVersion();
                if (CollectionUtil.isEmpty(androidVersions)) {
                    return Result.build(null, ResultCodeEnum.NO_DATA);
                }
                int currentLastDigit = getCurrentLastDigit(currentVersion);
                // 过滤版本列表
                List<AndroidVersion> filteredAndroidVersions = androidVersions.stream()
                        .filter(version -> {
                            String versionNumber = version.getAndroidVersion();
                            int lastDigit = getCurrentLastDigit(versionNumber);
                            return lastDigit > currentLastDigit;
                        })
                        .sorted(Comparator.comparing(AndroidVersion::getUpdateTime))
                        .collect(Collectors.toList());
                // 返回过滤后的版本列表或其他处理
                return Result.ok(filteredAndroidVersions);
            case "ios":
                if(currentVersion.split("\\.").length<2){
                    return Result.build(null, ResultCodeEnum.ARGUMENT_VALID_ERROR);
                }
                List<IosVersion> iosVersions = userInfoMapper.getIosVersion();
                if (CollectionUtil.isEmpty(iosVersions)) {
                    return Result.build(null, ResultCodeEnum.NO_DATA);
                }
                // 将版本号转换为整数，用于比较
                long currentVersionInt = convertVersionToComparable(currentVersion);
                // 过滤版本列表
                List<IosVersion> filteredIosVersions = iosVersions.stream()
                        .filter(version -> {
                            String versionNumber = version.getAppleVersion();
                            long versionInt = convertVersionToComparable(versionNumber);
                            return versionInt > currentVersionInt;
                        })
                        .sorted(Comparator.comparing(IosVersion::getUpdateTime))
                        .collect(Collectors.toList());

                // 返回过滤后的版本列表
                return Result.ok(filteredIosVersions);

            default:
                return Result.build(null, ResultCodeEnum.ILLEGAL_REQUEST);
        }
    }

    public int getCurrentLastDigit(String currentVersion) {
        // 提取当前版本号的末位数字
        int lastDotIndex = currentVersion.lastIndexOf('.'); // 获取最后一个"."的位置
        String lastSegment = ""; // 初始化子串

        if (lastDotIndex != -1) { // 确保字符串中至少有一个"."
            lastSegment = currentVersion.substring(lastDotIndex + 1); // 从最后一个"."之后开始截取
        } else {
            // 如果没有"."，则整个字符串都是数字
            lastSegment = currentVersion;
        }

        int currentLastDigit = Integer.parseInt(lastSegment);
        return currentLastDigit;
    }

    public long convertVersionToComparable(String version) {
        String[] parts = version.split("\\.");
        long major = Long.parseLong(parts[0]);
        long minor = Long.parseLong(parts[1]);

        // 如果存在第三部分，则转换并乘以基数（例如1000）
        if (parts.length > 2) {
            long patch = Long.parseLong(parts[2]);
            minor = minor * 1000 + patch;
        }

        return major * 1000000 + minor;
    }

}
